package versuch

import org.juiceshop.groovy.orientdb.Database
import org.juiceshop.groovy.orientdb.OrientDbExtensions;

import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx
import com.orientechnologies.orient.core.index.OIndex;
import com.orientechnologies.orient.core.metadata.schema.OType;
import com.orientechnologies.orient.core.query.nativ.ONativeSynchQuery;
import com.orientechnologies.orient.core.query.nativ.OQueryContextNative;
import com.orientechnologies.orient.core.record.impl.ODocument
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;


OrientDbExtensions.init()

DBDIR='db'
DBURL='memory:'+DBDIR

new File(DBDIR).deleteDir()


db = new Database(DBURL)
persons = db.table('Person')
cities = db.table('City','name')

if (!db.exists()) {
	println('create database')
	db.create {
		db.schema {
			dbClass('Person')
			dbClass('City'){
				println '- in dbClass'
				property('name',OType.STRING) { 
					println '- in property'
					def ind = indexUnique()
					assert ind
				}
			}
		}
//		db.metadata.schema.createClass('Person')
//		def cityClass = db.metadata.schema.createClass('City')
//		cityClass.createProperty("name", OType.STRING)
//		db.commandSQL("CREATE INDEX City.name unique")
		
		def luke = persons.create(name:'Luke',surname:'Skywalker')
		luke.city = cities.create(name:"Rome",zip:9000,country:"Italy")
		// SAVE THE DOCUMENT
		luke.save()
		
		persons.save(name:'Klaus',surname:'Schulz',
			city:cities.create(name:"Berlin",zip:1000,country:"Germany"))
		
		def berlin = cities.find(name:'Berlin')
		assert berlin
		assert berlin.name=='Berlin'
		
		persons.save(name:'Heinz',surname:'Schulz',city:berlin)
		
		assert persons.count()==3
		assert cities.count()==2
		
		persons.browse { println it }
		cities.browse { println it }
		
		persons.browse ('city.name':'Berlin') {
			assert it.city.name=='Berlin'
		}
		
	}
}

println("*** Test Native ***")
db.connect('admin','admin') {
	def res = persons.query {
		it.city.zip.eq(1000).and().name.like("K%")
	}
	assert res.size()==1
	assert res[0].name=='Klaus'
}

println('*** Test SQL ***')
db.connect {
	def res = db.querySQL("select * from Person where city.zip=1000 and name like 'K%'")
	assert res.size()==1
	assert res[0].name=='Klaus'
	
	def req = db.prepare("select * from Person where city.zip=? and name like ?")
	res = req.execute(1000,'K%')
	assert res.size()==1
	assert res[0].name=='Klaus'
	
	req = db.prepare("select * from Person where city.zip=:zip and name like :name")
	res = req.execute(zip:1000,name:'K%')
	assert res.size()==1
	assert res[0].name=='Klaus'
	
	res = db.querySQL("select * from Person where city.zip=${1000} and name like ${'K%'}")
	assert res.size()==1
	assert res[0].name=='Klaus'

}

println('*** Test Find ***')
db.connect {
	def res = persons.findAll('city.zip':1000,name:'K%')
	assert res.size()==1
	assert res[0].name=='Klaus'

	res = persons.findAllX('city.zip':1000,name:'K%')
	assert res.size()==1
	assert res[0].name=='Klaus'
}

println('*** Test Command ***')
db.connect {
	def res = db.commandSQL("update Person set surname='Seawalker' where name='Luke'")
	assert res==1
	assert persons.find(name:'Luke').surname=='Seawalker'
	
	res = db.commandSQL("update Person set surname=? where name=?",'Woodwalker','Luke')
	assert res==1
	assert persons.find(name:'Luke').surname=='Woodwalker'

	res = db.commandSQL("update Person set surname=${'Skywalker'} where name=${'Luke'}")
	assert res==1
	assert persons.find(name:'Luke').surname=='Skywalker'

}

println('*** Test Update ***')
db.connect {
	def klaus = persons.find(name:'Klaus')
	assert klaus
	klaus.city.zip += 1
	klaus.save()
	assert cities['Berlin'].zip==1001
}

println("*** Test Transaction ***")
db.connect {
	def klaus = persons.find(name:'Klaus')
	klaus.surname='Schulz'
	klaus.save()

	klaus = persons.find(name:'Klaus')
	assert klaus.surname=='Schulz'
	try {
		db.inTransaction {
			klaus.surname = 'Meier'
			klaus.save()
			assert persons.find(name:'Klaus').surname=='Meier'
			throw new IllegalStateException()
		}
	} catch (IllegalStateException ex) { /**/ }

	klaus = persons.find(name:'Klaus')
	assert klaus.surname=='Schulz'
	db.inTransaction {
		klaus.surname = 'Meier'
		klaus.save()
	}

	assert persons.find(name:'Klaus').surname=='Meier'
}


println('*** Test Get ***')
db.connect {
	def index = cities.index('name')
	def res = index['Rome']
	assert db.load(res).name=='Rome'
	
	assert cities['Rome'].name == 'Rome'
}


void dumpList(List list) {
	list.each { println it }
}
